home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-12-08 | 42.5 KB | 1,262 lines | [TEXT/R*ch] |
- C.S.M.P. Digest Fri, 09 Oct 92 Volume 1 : Issue 179
-
- Today's Topics:
-
- ColorTables: misc. tidbits and code
- Keeping the cursor visible
- Zbasic+System 6/7 Speed
- Function missing from MPW C library?
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
-
- The digest is a collection of article threads from the internet newsgroup
- comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
- regularly and want an archive of the discussions. If you don't know what a
- newsgroup is, you probably don't have access to it. Ask your systems
- administrator(s) for details. (This means you can't post questions to the
- digest.)
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- cs.uoregon.edu). Article threads are not added to the digest until the last
- article added to the thread is at least one month old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
- [128.223.8.8] in the directory /pub/mac/csmp-digest. Be sure to read the
- file /pub/mac/csmp-digest/README before downloading any files. The most
- recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
- directory /info-mac/digest/csmp. If you don't have ftp capability, the sumex
- archive has a mail server; send a message with the text '$MACarch help' (no
- quotes) to LISTSERV@ricevm1.rice.edu for more information.
-
- The digest is also available via email. Just send a note saying that you
- want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
- automatically receive each new issue as it is created. Sorry, back issues
- are not available through the mailing list.
-
- Send administrative mail to mkelly@cs.uoregon.edu.
-
-
- -------------------------------------------------------
-
- From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
- Subject: ColorTables: misc. tidbits and code
- Date: 3 Sep 92 16:32:09 GMT
- Organization: Kalamazoo College
-
- This article starts off with some AppleLink mail from Forrest Tanaka,
- telling you more than you ever wanted to know about color tables, and
- ends with a fair amount of ANSI C source code for manipulating them.
- This is, in short, a hodgepodge of answers and solutions. If you're
- a little confused about color graphics on the Mac (who isn't?!),
- well, who knows--this may clear up something for you.
-
- Please note that the code is copyrighted and may not be used directly
- in a for-profit program. That's 'cause my company paid me to write
- it and it's not fair for you to steal it. Sorry. If you want to use
- it, fix a bug for me. (There must be at least one.) Otherwise,
- you're free to use it directly in private or free programs, and to
- write your own code based on mine.
-
- Comments, especially on the source code, are heartily welcomed.
-
- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy
-
-
-
-
-
- Item 5744291 10-July-92 16:02PDT
- From: DEVSUPPORTJ Developer Support Center
- To: J.MCCARTHYJ MCE-Lawrence Prod, J McCarthy
- Sub: RE-ColorTable code-level Q's
-
- July 10, 1992
-
- Hi Jamie
-
- I received your questions about color tables, and since there are
- several questions, IUll put the text of your question in a narrow
- paragraph and respond to each one in the normal paragraphs
- afterwards.
-
- When drawing offscreen, every CQD routine will handle both
- indexed and sequential tables properly; in addition,
- CopyBits will handle a "paletted" table for its source
- PixMap. Right?
-
- Yes. If the source PixMap to CopyBits is paletted and the destination
- is a window with a palette, then CopyBits uses the value field of
- each ColorSpec record as a palette index for each pixel, which is of
- course the whole idea behind paletted color tables. If the
- destination is anything else, then bit 14 of ctFlags is ignored and
- the color table is treated as either indexed or sequential depending
- on the value of bit 15. Bit 14 is also ignored when its color
- tableUs PixMap is used as the destination to CopyBits.
-
- IM V-136, contradictorially, says "The ctFlags field is
- significant for gDevices only," and "Color tables that are
- part of [non-GDevice] pixMaps have this bit clear." What
- this means is, "Clear your own ctFlags, use indexed tables,
- and don't mess with a GDevice's ctFlags." Right?
-
- Inside Macintosh is simply wrong on this point, though it was the
- popular belief for quite a while. The truth is that QuickDraw reads
- ctFlags regardless of whether the color tableUs PixMap belongs to a
- GDevice, a GWorld, or is one that you created. If you create your
- own PixMap and want to use a sequential color table, set this bit.
- If you want an indexed color table, clear this bit. QuickDraw will
- read this bit and do the right thing. I personally always make
- indexed color tables because I happen to be more comfortable with
- them, but you can make a sequential one if you want, and QuickDraw
- will have no problems with it.
-
- ItUs true that all screen GDevices have color tables which are
- sequential, but that doesnUt mean that all GDevices must have
- sequential color tables. If you make a GDevice yourself, say for
- off-screen drawing, then you can have either a sequential or indexed
- color table. QuickDraw will read the most significant bit of ctFlags
- and act accordingly.
-
-
- I understand that video drivers expect sequential tables.
- But, is there anything at all wrong with mixing and
- matching sequential and indexed tables when they don't
- belong to GDevices?
-
- No, no problem at all. In fact, as I mentioned, you can mix and match
- even if a color table belongs to a GDevice. The only thing you canUt
- do is change the color table of a screenUs GDevice directly.
-
-
- Must an indexed table be sorted?
-
- No. You can arrange an indexed color table in random order if you
- want to, as long as you set the value field of each the color
- specification records to the pixel value that you want for each
- color. For example, these two four-entry color tables are identical
- assuming ctFlags is zero:
-
- Entry value rgb Entry value rgb
- 0 0 white 0 2 mauve
- 1 1 green 1 1 green
- 2 2 mauve 2 3 black
- 3 3 black 3 0 white
-
-
- IM V-138 says "...when the Color2Index routine is called,
- it can find the best match to the full 48-bit resolution
- available in a colorSpec." Really? Even if the inverse
- table's only 3 bits and my color table consists of (for
- example) a 256-shade gradation from black to white?
- Doesn't that require appending a whole lot of information
- after the inverse table?
-
- Inside Macintosh is right, and so are you. If you have two colors
- that differ only in the least significant bit of each of their
- components, Color2Index will be able to tell the difference. The
- inverse-table look-up is just the first step; itUs a coarse
- estimation of what the final pixel value is. At the end of the
- inverse table is a linked list of colors, called the hidden-color
- list. After the inverse-table look-up is complete, this coarse
- estimate is fine-tuned using the hidden-color list so that
- Color2Index can tell the difference between two colors down to the
- last bit. Color QuickDraw doesnUt always use the hidden-color list
- though. If you use the arithmetic modes with CopyBits, only the
- coarse, inverse-table look-up is done. If you use dithering with
- CopyBits, the hidden-color list isnUt used either.
-
-
- What will happen if you ask CQD to manipulate a table whose
- top two ctFlags bits are 11? (Just out of curiosity.)
-
- IUve done this, and itUs fine. If the PixMap that owns this color
- table is used as a source to CopyBits and if the destination is a
- window with a palette, this PixMap is treated as a paletted color
- table. If the destination is a window without a palette or a PixMap
- thatUs not associated with a window at all, the color table is
- treated as a sequential color table. If the PixMap is used as the
- destination to CopyBits, then itUs just treated as a sequential color
- table. Think of it this way: bit 14 has an effect if the color table
- belongs to the source PixMap to CopyBits and a window with a palette
- is the destination. In any other case, bit 14 is ignored and bit 15
- tells QuickDraw what to do.
-
-
- Well, I hope that covers everything. If you need any clarifications
- or any more help, just let me know!
-
- - -- Forrest
-
-
-
-
-
- /*
- * ColorTableUtils.h
- *
- * Copyright ) 1992 by Lawrence Productions, Inc. All Rights Reserved.
- *
- * This code may not be used in any for-profit program without the
- * written permission of Lawrence Productions, Inc.
- *
- */
-
-
-
- /********************************/
-
- #pragma once
-
- /********************************/
-
- /*
- * Note that the values of these three constants happen to equal the
- * top two bits of the ctFlags field. The macro for getColorTableMode()
- * is the only thing that depends on this fact.
- */
-
- enum {
- kIndexedColorTable = 0x00,
- kPalettedColorTable = 0x01,
- kSequentialColorTable = 0x02
- } ;
-
- /********************************/
-
- /*
- * Determine the mode of a color table.
- */
-
- short getColorTableMode(CTabPtr theTablePtr);
- #define getColorTableMode(theTablePtr) ( \
- ((unsigned short)(theTablePtr)->ctFlags) >> 14 )
- #define colorTableIsIndexed(theTablePtr) \
- (getColorTableMode(theTablePtr) == kIndexedColorTable)
- #define colorTableIsPaletted(theTablePtr) \
- (getColorTableMode(theTablePtr) == kPalettedColorTable)
- #define colorTableIsSequential(theTablePtr) \
- (getColorTableMode(theTablePtr) == kSequentialColorTable)
-
-
- /*
- * Determine whether a color table is sorted. Naturally, it's designed
- * for indexed tables, but works (trivially) with sequential and
- * paletted tables too.
- */
-
- Boolean colorTableIsSorted(CTabPtr theTable);
- #define assertColorTableIsSorted(theTable) ASSERT(colorTableIsSorted(theTable));
-
-
- /*
- * Find an entry's offset in a color table. Naturally, it's designed
- * for indexed tables, but works (trivially) on sequential tables too.
- * Paletted tables may have none or several entries that point to a
- * particular palette entry, and this routine will not attempt to
- * search them, returning kNoEntryFound instead.
- *
- * For all tables, the output is the index into the ctTable field.
- */
-
- #define kNoEntryFound (-1)
- short findEntryInSortedTable(CTabPtr theTable, short wEntry);
-
-
- /*
- * Add an entry to a color table. Returns TRUE if the entry was
- * actually added (i.e. if the table's size went up), and FALSE if
- * the entry wasn't added. The entry number is of course in the
- * value field.
- *
- * For this one, the table really _does_ have to be indexed.
- */
-
- Boolean addEntryToSortedIndexedTable(CTabHandle theIndexedTable, ColorSpec *theColorSpec);
-
-
- /*
- * Convert color storage modes back 'n' forth. These allocate memory
- * and don't alter the original table.
- *
- * You can't switch to or from a paletted color table without knowing
- * what the palette is, so no routines are provided for that.
- */
-
- CTabHandle makeIndexedFromSequential(CTabHandle theSequentialTable);
- CTabHandle makeSequentialFromSortedIndexed(CTabHandle theIndexedTable, RGBColor *fillColor);
-
-
- /*
- * Sort a table's entries. Does nothing if the table is sequential
- * or paletted.
- */
-
- void sortIndexedTable(CTabHandle theTable);
-
-
- /*
- * Compare two tables, even if they use different modes. Paletted
- * tables can't be compared to anything, and so always return FALSE.
- * If both tables are indexed, they must both be sorted.
- */
-
- Boolean colorTablesAreEquivalent(CTabHandle table1, CTabHandle table2, RGBColor *fillColor);
-
-
- /*
- * Functions to manipulate the number of entries of a color table.
- * The "get" function is simple, so it comes with a macro. The
- * others alter the ctSize field and resize the handle; "set"
- * sets the number of entries directly, while "change" adds or
- * subtracts from the current number of entries. If the table's
- * size changes, it (and memory) may be moved, even if it's
- * locked. If the table is lengthened, the new entries contain
- * garbage.
- */
-
- short getNCTEntries(CTabPtr theTable);
- #define getNCTEntries(theTable) ((theTable)->ctSize+1)
- void setNCTEntries(CTabHandle theTable, short nEntries);
- void changeNCTEntries(CTabHandle theTable, short nEntries);
-
-
- /*
- * Quickie macros to convert a table's depth to the maximum number of
- * entries, and to convert a number of entries to a minimum depth.
- *
- * The function prototypes are only there to do a little parameter
- * type-checking; since the macros do their conversion in place,
- * the functions wouldn't actually do anything if you were to call
- * them. (And if they took pointers instead of doing the work in
- * place, you couldn't use register variables, ick.) If the functions
- * ever actually _do_ get called, they pop into the debugger with
- * an appropriate message.
- */
-
- void convertDepthToMaxNEntries(short d, short n);
- #define convertDepthToMaxNEntries(d,n) \
- { short ___depth=(d); \
- for ((n)=1; ___depth>=1; --___depth) \
- (n) <<= 1; }
-
- void convertNEntriesToMinDepth(short n, short d);
- #define convertNEntriesToMinDepth(n,d) \
- { short ___nEntries=(n); \
- for ((d)=0; ___nEntries>1; ___nEntries>>=1) \
- ++(d); }
-
-
-
-
-
- /*
- * ColorTableUtils.c
- *
- * Copyright ) 1992 by Lawrence Productions, Inc. All Rights Reserved.
- *
- * This code may not be used in any for-profit program without the
- * written permission of Lawrence Productions, Inc.
- *
- */
-
-
-
- /********************************/
-
- #include "ColorTableUtils.h"
-
- /********************************/
-
- /*
- * You'll need to put qsort.c in your project.
- */
- #include <stdlib.h>
-
- /********************************/
-
- /*
- * The only thing used from JamieUtilities.c is "jmemcmp()," which is
- * just a clone of memcmp(). (I save 100 bytes of object code by
- * taking it out of mem.c, because memcmp() is the only function in
- * there that I would ever use. I guess I'm a fanatic.) Anyway, if
- * you don't have JamieUtilities, just #include <string.h>, drop mem.c
- * in your project, and change "jmemcmp" to "memcmp".
- */
- #include <JamieUtilities.h>
-
- /********************************/
-
-
-
- short (getColorTableMode)(CTabPtr theTable)
- {
- ASSERT(theTable != NULL);
-
- switch ( ((unsigned short) (theTable)->ctFlags) >> 14 ) {
-
- case 0x00: return kIndexedColorTable; break;
- case 0x01: return kPalettedColorTable; break;
- case 0x02: return kSequentialColorTable; break;
- default: ASSERT(0); return -1; break;
-
- }
- }
-
-
-
- Boolean colorTableIsSorted(CTabPtr theTable)
- {
- register ColorSpec *theCTTable;
- register short cPosition, nEntriesMinusOne, lastEntry;
-
- ASSERT(theTable != NULL);
-
- if (!colorTableIsIndexed(theTable)) {
- return TRUE;
- }
-
- theCTTable = &theTable->ctTable[0];
- nEntriesMinusOne = theTable->ctSize;
- cPosition = 0;
- lastEntry = -1;
- for (cPosition = 0; cPosition <= nEntriesMinusOne; ++cPosition) {
-
- register short thisEntry;
-
- if ( (thisEntry=theCTTable[cPosition].value) < lastEntry) {
- return FALSE;
- } else {
- lastEntry = thisEntry;
- }
-
- }
-
- return TRUE;
- }
-
-
-
- /*
- * Returns TRUE iff the entry was found. If the entry was not found,
- * it returns the position where it should be inserted.
- */
-
- Boolean engineFindEntryInSortedTable(CTabPtr tablePtr, register short wEntry, short *thePosition);
- Boolean engineFindEntryInSortedTable(CTabPtr tablePtr, register short wEntry, short *thePosition)
- {
- /*
- * I'm 99.9% sure this code will find an existing entry, but only
- * 80% sure that it'll return the proper position for a nonexisting
- * one, the proper position being the entry to the right. I suppose
- * I should test it rigorously one of these days...
- */
-
- register unsigned short cPosition;
- register unsigned short leftBounds, rightBounds;
- register ColorSpec *theCSpecArray;
-
- if (!colorTableIsIndexed(tablePtr)) {
- if (wEntry <= tablePtr->ctSize) {
- *thePosition = wEntry;
- return TRUE;
- } else {
- *thePosition = tablePtr->ctSize;
- return FALSE;
- }
- }
-
- assertColorTableIsSorted(tablePtr);
-
- theCSpecArray = tablePtr->ctTable;
- leftBounds = 0; rightBounds = tablePtr->ctSize + 1 - 1;
- cPosition = rightBounds / 2;
-
- while (leftBounds < rightBounds) {
-
- if (theCSpecArray[cPosition].value == wEntry) {
- *thePosition = cPosition;
- return TRUE;
- } else {
- if (theCSpecArray[cPosition].value < wEntry) {
- leftBounds = cPosition;
- cPosition += rightBounds + 1;
- cPosition >>= 1;
- } else {
- rightBounds = cPosition;
- cPosition += leftBounds;
- cPosition >>= 1;
- }
- }
-
- }
-
- /*
- * If the requested entry is not there, we want the entry that's
- * right _after_ where it would go.
- */
-
- if (theCSpecArray[cPosition].value < wEntry) {
- ++cPosition;
- }
-
- ASSERT(cPosition == tablePtr->ctSize+1 || theCSpecArray[cPosition].value > wEntry);
- ASSERT(cPosition == 0 || theCSpecArray[cPosition-1].value < wEntry);
-
- *thePosition = cPosition;
- return FALSE;
- }
-
-
- short findEntryInSortedTable(CTabPtr theTable, short wEntry)
- {
- short thePosition;
-
- if (engineFindEntryInSortedTable(theTable, wEntry, &thePosition)) {
- return thePosition;
- } else {
- return kNoEntryFound;
- }
- }
-
-
-
- Boolean addEntryToSortedIndexedTable(CTabHandle theIndexedTable, ColorSpec *theColorSpec)
- {
- register CTabPtr theIndexedTabPtr;
- short wEntry;
- short thePosition;
-
- ASSERT( colorTableIsIndexed(*theIndexedTable) );
-
- wEntry = theColorSpec->value;
-
- theIndexedTabPtr = *theIndexedTable;
- if (engineFindEntryInSortedTable(theIndexedTabPtr, wEntry, &thePosition)) {
-
- /* No need to add the entry, it's already there. */
-
- theIndexedTabPtr->ctTable[thePosition] = *theColorSpec;
-
- return FALSE;
-
- } else {
-
- long newSize;
-
- newSize = sizeof(ColorTable)
- + sizeof(ColorSpec) * ( theIndexedTabPtr->ctSize + 1 );
- SetHandleSize( (Handle) theIndexedTable, newSize );
- theIndexedTabPtr = *theIndexedTable;
-
- BlockMove( &theIndexedTabPtr->ctTable[thePosition],
- &theIndexedTabPtr->ctTable[thePosition]+1,
- (theIndexedTabPtr->ctSize+1 - thePosition) * sizeof(ColorSpec) );
-
- theIndexedTabPtr->ctTable[thePosition] = *theColorSpec;
-
- return TRUE;
-
- }
- }
-
-
-
- CTabHandle makeIndexedFromSequential(CTabHandle theSequentialTable)
- {
- CTabHandle theIndexedTable;
- register ColorSpec *theSequentialColorSpecPtr;
- register ColorSpec *theIndexedColorSpecPtr;
- register CTabPtr theSequentialTablePtr;
- register CTabPtr theIndexedTablePtr;
- register short cIndexedEntry;
- register short nSequentialEntriesMinusOne;
-
- ASSERT(theSequentialTable != NULL);
- ASSERT(colorTableIsSequential(*theSequentialTable));
-
- nSequentialEntriesMinusOne = (**theSequentialTable).ctSize;
-
- theIndexedTable = (CTabHandle) NewHandle( sizeof(ColorTable)
- + sizeof(ColorSpec) * nSequentialEntriesMinusOne );
- theIndexedTablePtr = *theIndexedTable;
- theSequentialTablePtr = *theSequentialTable;
-
- theIndexedTablePtr->ctSeed = theSequentialTablePtr->ctSeed;
- theIndexedTablePtr->ctFlags = theSequentialTablePtr->ctFlags
- & 0x3FFF
- | 0x0000;
- theIndexedTablePtr->ctSize = nSequentialEntriesMinusOne;
- theIndexedColorSpecPtr = &theIndexedTablePtr->ctTable[0];
- theSequentialColorSpecPtr = &theSequentialTablePtr->ctTable[0];
-
- for (cIndexedEntry = 0;
- cIndexedEntry <= nSequentialEntriesMinusOne;
- ++cIndexedEntry) {
-
- theIndexedColorSpecPtr->value = cIndexedEntry;
- (theIndexedColorSpecPtr++)->rgb = (theSequentialColorSpecPtr++)->rgb;
-
- }
-
- return theIndexedTable;
- }
-
-
-
- CTabHandle makeSequentialFromSortedIndexed(CTabHandle theIndexedTable, RGBColor *fillColor)
- {
- CTabHandle theSequentialTable;
- register ColorSpec *theIndexedColorSpecPtr;
- register ColorSpec *theSequentialColorSpecPtr;
- register CTabPtr theIndexedTablePtr;
- register CTabPtr theSequentialTablePtr;
- register short cSequentialEntry, nextIndexedEntry, nextIndexedPosition;
- register short nIndexedEntriesMinusOne, nSequentialEntriesMinusOne;
-
- ASSERT(theIndexedTable != NULL);
- ASSERT(colorTableIsIndexed(*theIndexedTable));
- assertColorTableIsSorted(*theIndexedTable);
-
- nIndexedEntriesMinusOne = (**theIndexedTable).ctSize;
- nSequentialEntriesMinusOne =
- (**theIndexedTable).ctTable[nIndexedEntriesMinusOne].value;
-
- theSequentialTable = (CTabHandle) NewHandle( sizeof(ColorTable)
- + sizeof(ColorSpec) * nSequentialEntriesMinusOne );
- theSequentialTablePtr = *theSequentialTable;
- theIndexedTablePtr = *theIndexedTable;
-
- theSequentialTablePtr->ctSeed = theIndexedTablePtr->ctSeed;
- theSequentialTablePtr->ctFlags = theIndexedTablePtr->ctFlags
- & 0x3FFF
- | 0x8000;
- theSequentialTablePtr->ctSize = nSequentialEntriesMinusOne;
- theSequentialColorSpecPtr = &theSequentialTablePtr->ctTable[0];
- theIndexedColorSpecPtr = &theIndexedTablePtr->ctTable[0];
-
- nextIndexedPosition = 0;
- nextIndexedEntry = theIndexedColorSpecPtr[0].value;
- for (cSequentialEntry = 0;
- cSequentialEntry <= nSequentialEntriesMinusOne;
- ++cSequentialEntry) {
-
- ASSERT(cSequentialEntry <= nextIndexedEntry);
-
- if (cSequentialEntry == nextIndexedEntry) {
- theSequentialColorSpecPtr->value = cSequentialEntry;
- (theSequentialColorSpecPtr++)->rgb = (theIndexedColorSpecPtr++)->rgb;
- if (++nextIndexedPosition > nIndexedEntriesMinusOne) {
- nextIndexedEntry = MAXINT;
- } else {
- nextIndexedEntry = theIndexedColorSpecPtr->value;
- }
- } else {
- theSequentialColorSpecPtr->value = 0;
- (theSequentialColorSpecPtr++)->rgb = *fillColor;
- }
-
- }
-
- return theSequentialTable;
- }
-
-
-
- static int compareColorSpecValues(const ColorSpec *color1, const ColorSpec *color2);
- static int compareColorSpecValues(register const ColorSpec *color1,
- register const ColorSpec *color2)
- {
- if (color1->value != color2->value) {
- if (color1->value < color2->value) {
- return -1;
- } else {
- return 1;
- }
- }
- return 0;
- }
-
- void sortIndexedTable(CTabHandle theTable)
- {
- register CTabPtr theTablePtr;
- short oldState;
-
- ASSERT(theTable != NULL);
-
- theTablePtr = *theTable;
- if (!colorTableIsIndexed(theTablePtr)) {
- return ;
- }
-
- oldState = HGetState( (Handle) theTable );
- HLock( (Handle) theTable);
- qsort( &theTablePtr->ctTable[0],
- theTablePtr->ctSize+1,
- sizeof(ColorSpec),
- (__cmp_func) compareColorSpecValues);
- HSetState( (Handle) theTable, oldState );
-
- assertColorTableIsSorted(theTablePtr);
- }
-
-
-
- Boolean colorTablesAreEquivalent(CTabHandle table1, CTabHandle table2, RGBColor *fillColor)
- {
- Boolean areEquivalent;
-
- ASSERT(table1 != NULL);
- ASSERT(table2 != NULL);
-
- areEquivalent = TRUE;
-
- if (colorTableIsPaletted(*table1) || colorTableIsPaletted(*table2)) {
- /* Paletted tables can't be compared to anything. */
- return FALSE;
- }
-
- if (colorTableIsSequential(*table1) || colorTableIsSequential(*table2)) {
-
- /*
- * Convert one of the tables to sequential, if need be, and compare.
- */
-
- register CTabPtr t1, t2;
- register short nEntriesMinusOne;
- CTabHandle convertedTable;
-
- convertedTable = NULL;
- if (colorTableIsIndexed(*table1)) {
- assertColorTableIsSorted(*table1);
- convertedTable = makeSequentialFromSortedIndexed(table1, fillColor);
- t1 = *convertedTable;
- t2 = *table2;
- } else if (colorTableIsIndexed(*table2)) {
- assertColorTableIsSorted(*table2);
- convertedTable = makeSequentialFromSortedIndexed(table2, fillColor);
- t1 = *table1;
- t2 = *convertedTable;
- }
-
- if ( (nEntriesMinusOne=t1->ctSize) != t2->ctSize) {
-
- areEquivalent = FALSE;
-
- } else {
-
- register short cEntry;
-
- for (cEntry = 0; cEntry <= nEntriesMinusOne; ++cEntry) {
-
- /*
- * When comparing sequential tables, ignore the value field.
- */
-
- if ( t1->ctTable[cEntry].rgb.red != t2->ctTable[cEntry].rgb.red
- || t1->ctTable[cEntry].rgb.green != t2->ctTable[cEntry].rgb.green
- || t1->ctTable[cEntry].rgb.blue != t2->ctTable[cEntry].rgb.blue ) {
-
- areEquivalent = FALSE;
- break;
-
- }
-
- }
-
- }
-
- DisposHandle( (Handle) convertedTable );
-
- } else {
-
- /*
- * Leave both tables indexed, and compare. Assume they're sorted.
- */
-
- register CTabPtr t1, t2;
- register short nEntriesMinusOne;
-
- t1 = *table1;
- t2 = *table2;
-
- assertColorTableIsSorted(t1);
- assertColorTableIsSorted(t2);
-
- if ( (nEntriesMinusOne=t1->ctSize) != t2->ctSize) {
-
- areEquivalent = FALSE;
-
- } else {
-
- register short cEntry;
-
- areEquivalent = ( jmemcmp( // jmemcmp() is just a memcmp() clone
- &t1->ctTable[0],
- &t2->ctTable[0],
- sizeof(ColorSpec)*(nEntriesMinusOne+1)
- ) == 0);
-
- #if you_want_it_spelled_out_for_you
- for (cEntry = 0; cEntry <= nEntriesMinusOne; ++cEntry) {
- if ( t1->ctTable[cEntry].value != t2->ctTable[cEntry].value
- || t1->ctTable[cEntry].rgb.red != t2->ctTable[cEntry].rgb.red
- || t1->ctTable[cEntry].rgb.green != t2->ctTable[cEntry].rgb.green
- || t1->ctTable[cEntry].rgb.blue != t2->ctTable[cEntry].rgb.blue ) {
- areEquivalent = FALSE;
- break;
- }
- }
- #endif
-
- }
-
- }
-
- return areEquivalent;
- }
-
-
-
- short (getNCTEntries)(CTabPtr theTable)
- {
- return theTable->ctSize + 1;
- }
-
-
-
- void setNCTEntries(CTabHandle theTable, short nEntries)
- {
- short oldState;
-
- ASSERT(nEntries >= 0);
- ASSERT(nEntries <= 256); // arbitrary
-
- if (getNCTEntries(*theTable) == nEntries) return;
-
- (**theTable).ctSize = nEntries-1;
-
- oldState = HGetState( (Handle) theTable );
- HUnlock( (Handle) theTable );
- SetHandleSize( (Handle) theTable,
- sizeof(ColorTable) + (nEntries-1)*sizeof(ColorSpec));
- HSetState( (Handle) theTable, oldState);
- }
-
-
-
- void changeNCTEntries(CTabHandle theTable, short nEntries)
- {
- if (nEntries == 0) return;
-
- setNCTEntries(theTable, getNCTEntries(*theTable) + nEntries);
- }
-
-
-
- void (convertDepthToMaxNEntries)(short d, short n)
- {
- DebugStr("\pconvertDepthToMaxNEntries was somehow called!");
- }
-
-
-
- void (convertNEntriesToMinDepth)(short n, short d)
- {
- DebugStr("\pconvertNEntriesToMinDepth was somehow called!");
- }
-
- +++++++++++++++++++++++++++
-
- From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
- Organization: Kalamazoo College
- Date: Fri, 4 Sep 1992 20:49:09 GMT
-
- k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes:
- >This article starts off with some AppleLink mail from Forrest Tanaka,
- >telling you more than you ever wanted to know about color tables, and
- >ends with a fair amount of ANSI C source code for manipulating them.
-
- I've already (sigh) found several bugs in my code. If you want an
- updated version, email me.
- - --
- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy
- The same people who love MS-DOS so much that they went to PC Expo,
- supported Ross Perot by an overwhelming margin. This should be
- telling you something.
-
- ---------------------------
-
- From: neath@brazil.psych.purdue.edu (Ian Neath)
- Subject: Keeping the cursor visible
- Date: 1 Sep 92 15:15:44 GMT
- Organization: Purdue University
-
- I have an application that cranks through a simulation model. Typically,
- it takes around an hour to do each run. I have set up an animated cursor
- to let me know the program is still cranking, but everytime the app
- writes to the TextEdit record, the cursor is hidden by (I assume) a
- call to ObscureCursor. Is it OK to keep calling ShowCursor to get
- my animated cursor back? IM says to balance ShowCursor with Hide-
- or ShieldCursor (or vice versa). My app seems to run fine, but since
- it takes so long to do each run, I don't want the program to bomb.
- Any advice, hints, etc appreciated. Thanks.
-
- - -ian
-
- - --
- Ian Neath, PhD | There are four kinds of people in this world:
- neath@psych.purdue.edu | cretins, fools, morons and lunatics - U. Eco
-
- +++++++++++++++++++++++++++
-
- From: wombat@claris.com (Scott Lindsey)
- Date: 2 Sep 92 01:14:13 GMT
- Organization: Claris Corporation, Vancouver WA
-
- In article <Btwnq8.LMv@mentor.cc.purdue.edu>, neath@brazil.psych.purdue.edu (Ian Neath) writes:
- >
- > writes to the TextEdit record, the cursor is hidden by (I assume) a
- > call to ObscureCursor. Is it OK to keep calling ShowCursor ...
-
- ShowCursor won't actually show the cursor if it's only obscured. I don't
- think there's a legal way to unobscure a cursor, however, setting the low-
- memory global CrsrNew = 0xFF forces it to really redraw. (CrsrNew is 0x8CE and
- is a 1-byte value).
-
- - --
- Scott Lindsey <wombat@claris.com>
-
- +++++++++++++++++++++++++++
-
- From: d88-jwa@dront.nada.kth.se (Jon W{tte)
- Date: 2 Sep 92 12:33:30 GMT
- Organization: Royal Institute of Technology, Stockholm, Sweden
-
- @claris.com (Scott Lindsey) writes:
-
- ShowCursor won't actually show the cursor if it's only obscured. I don't
- think there's a legal way to unobscure a cursor, however, setting the low-
- memory global CrsrNew = 0xFF forces it to really redraw. (CrsrNew is 0x8CE
- and is a 1-byte value).
-
- How abotu just calling InitCursor?
-
- It sets the cursor to an arrow, and shows it (and clears
- the show/hide count) and then you can call SetCursor to
- set it to the shape you want.
-
- - --
- Jon W{tte, h+@nada.kth.se, Sweden, Phone +46-8-107069
- White, Literate, Employed, Higher-Educated, Male, Straight and Not Poor.
- I must be a bad guy.
-
- +++++++++++++++++++++++++++
-
- From: lari@strauss.cs.unc.edu (Humayun Lari)
- Date: 2 Sep 92 21:54:21 GMT
- Organization: The University of North Carolina at Chapel Hill
-
- In article <15119@claris.com> wombat@claris.com (Scott Lindsey) writes:
- >In article <Btwnq8.LMv@mentor.cc.purdue.edu>, neath@brazil.psych.purdue.edu (Ian Neath) writes:
- >>
- >> writes to the TextEdit record, the cursor is hidden by (I assume) a
- >> call to ObscureCursor. Is it OK to keep calling ShowCursor ...
- >
- >ShowCursor won't actually show the cursor if it's only obscured. I don't
- >think there's a legal way to unobscure a cursor, however, setting the low-
- >memory global CrsrNew = 0xFF forces it to really redraw.
-
- If you're in charge of the writes to the TextEdit record (i.e. using TEKey),
- you could use TEInsert instead to prevent TextEdit from trying to be polite
- and calling ObscureCursor. Of course, TEInsert may be a bit slower, but in
- practice it seems to make little difference. And it's definitely *much* cleaner
- than having the cursor flicker every time a character is appended to the TE
- record (especially if you're porting a MS-DOS-based language interpreter that
- thinks a row of dots on the screen is a beautiful depiction of its progress).
-
- Humayun Lari
- (lari@cs.unc.edu)
-
- +++++++++++++++++++++++++++
-
- From: wombat@claris.com (Scott Lindsey)
- Date: 4 Sep 92 23:44:50 GMT
- Organization: Claris Corporation, Vancouver WA
-
- In article <D88-JWA.92Sep2133330@dront.nada.kth.se>, d88-jwa@dront.nada.kth.se (Jon W{tte) writes:
- >
- > @claris.com (Scott Lindsey) writes:
- >
- > ShowCursor won't actually show the cursor if it's only obscured. I don't
- > think there's a legal way to unobscure a cursor, however, setting the low-
- > memory global CrsrNew = 0xFF forces it to really redraw. (CrsrNew is 0x8CE
- > and is a 1-byte value).
- >
- > How abotu just calling InitCursor?
- >
- > It sets the cursor to an arrow, and shows it (and clears
- > the show/hide count) and then you can call SetCursor to
- > set it to the shape you want.
-
- I've lost the original message, but I think the issue was a progress cursor
- (beachball or something). In fact, in ClarisWorks, I use CrsrNew to show the
- cursor whenever the beachball comes up, just in case the cursor was obscured.
- That way, you won't be sitting there with an obscured spinning beachball.
-
- - --
- Scott Lindsey <wombat@claris.com>
-
- ---------------------------
-
- From: Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian)
- Subject: Zbasic+System 6/7 Speed
- Organization: FidoNet node 1:2603/204 - Not Even Odd, Forest Hills NY
- Date: Sat, 22 Aug 1992 20:25:01 GMT
-
- Most of you won't be familiar with Zedcor's Zbasic. A fine BASIC
- compiler, but perhaps you could throw in some hints about performance
- problems with System 7 which didn't exist under System 6.
-
- After a few months of System 7 use, I did install System 6.0.7 on a
- Syquest cartridge so that I'd be able to test some software I'd written
- with Zedcor's ZBasic with System 6, to make sure I didn't put in any
- inadvertent incompatibilities (of which I did find one and fix it.)
-
- I saw that the program ran about 3 times faster than under System 7! What
- exactly gets a program that was compiled with ZBasic that slow down so
- much in System 7 yet run so well under 6?
-
- Currently I had to implement double buffering of the modem and keyboard in
- order to get better performance. I'm running this on a IIcx which by no
- means is a slow machine. No a Quadra, but still faster than a Plus no
- less.
-
- Having called Zedcor, I've been told they're "never" going to release
- ZBasic 6.0. It will be called something like "Future" basic, and just as
- the last month's call confirmed their oppinion, "it will be available next
- month." :-)
-
- Is there something ZBasic does wrong in terms of WaitNextEvent or
- GetNextEvent? Certainly with ZBasic you have almost no control over these
- commands, as it does it's own event handling to buffer you away from the
- tool box. This is good for new programmers, but gets very cumbersome with
- me.
-
- How about the text writing routines (not TEdit routines, quickdraw text
- printing routines.) Have they been slowed down in System 7 with TType?
-
- I'm trying to track down the problem and perhaps lessen its effects if not
- remove it. Another thing I notice is that if I have any INIT's or CDEVs
- that grab the keyboard (QuickKeys, etc) the program slows down to hell.
- I'm grabbing keystrokes via system events (IE: DIALOG(16) function in
- ZBasic.)
-
- I'd hate to do so, but if I must I'll go in there with ResEdit and force
- Zbasic to produce the proper calls to WaitNextEvent with less of a delay
- time slice give up. Without doubt, I don't want to force my (potential)
- users to run this software under System 6.0.x :-)
-
- Any ideas would be greatly appreciated.
-
- * Freddie 1.3b2 * Do what thou whim shalt be a hole in the head!
-
- - --
- =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- Ray Arachelian - Internet: Ray.Arachelian@f204.n2603.z1.ieee.org
-
- +++++++++++++++++++++++++++
-
- From: mxmora@unix.SRI.COM (Matt Mora)
- Date: 25 Aug 92 16:03:14 GMT
- Organization: SRI International, Menlo Park, California
-
- In article <15639.2A996B26@zeus.ieee.org> Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian) writes:
-
- >Is there something ZBasic does wrong in terms of WaitNextEvent or
- >GetNextEvent? Certainly with ZBasic you have almost no control over these
- >commands, as it does it's own event handling to buffer you away from the
- >tool box. This is good for new programmers, but gets very cumbersome with
- >me.
-
- Yes it calls WNE/GNE before every line of your basic code. Not very
- efficient. Don't worry about it. Wait for future basic and
- upgrade as soon as you can.
-
-
-
- Matt
-
- - --
- ___________________________________________________________
- Matthew Mora | my Mac Matt_Mora@sri.com
- SRI International | my unix mxmora@unix.sri.com
- ___________________________________________________________
-
- +++++++++++++++++++++++++++
-
- From: Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian)
- Date: 30 Aug 92 20:30:07 GMT
- Organization: FidoNet node 1:2603/204 - Not Even Odd, Forest Hills NY
-
- On 08-25-92, MXMORA@UNIX.SRI.COM wrote to ALL:
-
- M> Yes it calls WNE/GNE before every line of your basic code. Not very
- M> efficient. Don't worry about it. Wait for future basic and upgrade
- M> as soon as you can.
-
- I do plan to get Future Basic, however, I've no intention of waiting
- around every time they tell me "Next Month" :-) I did find out what they
- do wrong. They not only call _GetNextEvent on every line, but they also
- make a LOT of calls to _SystemTask. I've even found a timing routine
- where they check the timer, and call _SystemTask over and over again.
- This really slows things down under System 7.... I've also tried to
- replace this with a call to WaitNextEvent, however, all I've managed to do
- was crash the machine. :-) See my other messages about patching...
-
-
- * Freddie 1.3b2 * Do what thou whim shalt be a hole in the head!
-
- - --
- =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- Ray Arachelian - Internet: Ray.Arachelian@f204.n2603.z1.ieee.org
-
- +++++++++++++++++++++++++++
-
- From: Glen.Stewart@f175.n2240.z1.ieee.org (Glen Stewart)
- Date: 25 Aug 92 14:21:24 GMT
- Organization: FidoNet node 1:2240/175 - The Associati, Grand Blanc MI
-
- Zedcor may have led you astray. I've been calling them on and off for the
- past 6 months. They have always told me that they ARE doing Zbasic 6.0!
-
- In fact, they told me late last week, that they have sent the upgrade notices
- to all the old users, and that 6.0 is now basically complete.
-
- Look forward to increased support for HyperCard externals!
-
-
- - --
- =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- Glen Stewart - Internet: Glen.Stewart@f175.n2240.z1.ieee.org
-
- +++++++++++++++++++++++++++
-
- From: Ray.Arachelian@f204.n2603.z1.ieee.org (Ray Arachelian)
- Date: 2 Sep 92 20:42:01 GMT
- Organization: FidoNet node 1:2603/204 - Not Even Odd, Forest Hills NY
-
- Generally, when I've called Zedcor, a female voice answered and told me "Not
-
- Yet." The "Future Basic" rumor as it may be was by a male voice. This was
-
- when I called on the weekend, so I assumed it was perhaps one of their long
-
- hour programmers.
-
- However the deadline seems to have lessened. Yesterday's call told me
- "Middle
- of this month" instead of "Next Month" so things are indeed getting
- better :-)
-
-
- - --
- =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
- Ray Arachelian - Internet: Ray.Arachelian@f204.n2603.z1.ieee.org
-
- ---------------------------
-
- From: mcnichol@terminator.psy.syr.edu (Brendan T. McNichols)
- Subject: Function missing from MPW C library?
- Date: Thu, 23 Jul 92 13:27:49 EDT
-
-
- Hi all,
-
- I am getting the following error message when building a project using
- MPW C:
-
- ### Link: Error: Undefined entry, name: (Error 28) "str2dec"
- Referenced from: _doscan in file: Alliance Drive
- :Development:MPW:Libraries:CLibraries:CLib881.o
- ### Link: Errors prevented normal completion.
- ### MPW Shell - Execution of KLSyn88.makeout terminated.
- ### MPW Shell - Execution of BuildProgram terminated.
-
- It seems to me that this means that the function "str2dec" is missing
- from the CSANELib881.o library. (It is declared in SANE.h.) I am new
- using MPW and I'm not sure if there's something here that I should have
- done but didn't. Does anyone know how to fix this problem? Is str2dec
- located in some other library? Can I get the code for str2dec and
- include it in the CSANELib881.o library?
-
- Thanks very much for any help,
- Brendan
-
- - --
- Brendan T. McNichols, Computer Support (315) 443-9902
- Psyracuse U. Sychology Dept. mcnichol@psy.syr.edu (NeXT)
- 430 Huntington Hall mcnichol@syr.edu
- Syracuse, NY 13244
-
- +++++++++++++++++++++++++++
-
- From: keith@taligent.com (Keith Rollin)
- Date: 24 Jul 92 19:38:37 GMT
- Organization: Taligent
-
- In article <1992Jul23.132750.12392@newstand.syr.edu>,
- mcnichol@terminator.psy.syr.edu (Brendan T. McNichols) writes:
- >
- > I am getting the following error message when building a project using
- > MPW C:
- >
- > ### Link: Error: Undefined entry, name: (Error 28) "str2dec"
- > Referenced from: _doscan in file: Alliance Drive
- > :Development:MPW:Libraries:CLibraries:CLib881.o
- > ### Link: Errors prevented normal completion.
- > ### MPW Shell - Execution of KLSyn88.makeout terminated.
- > ### MPW Shell - Execution of BuildProgram terminated.
- >
- > It seems to me that this means that the function "str2dec" is missing
- > from the CSANELib881.o library. (It is declared in SANE.h.) I am new
- > using MPW and I'm not sure if there's something here that I should have
- > done but didn't. Does anyone know how to fix this problem? Is str2dec
- > located in some other library? Can I get the code for str2dec and
- > include it in the CSANELib881.o library?
-
- There seem to b versions of str2dec in {Libraries}Runtime.o and
- {PLIbraries}PasLib.o. Whenever I have problems finding a library routine, I use
- the following script.
-
- Set Exit 0
- Set SearchExpression "`Request "Enter regular expression" || Echo '""'`"
- Exit if "{SearchExpression}" == ""
- For folder in "{Libraries}" "{PLibraries}" "{CLibraries}"
- Echo "Searching in {folder}"
- For file In `files -f -s -t "OBJ " "{folder}"`
- DumpObj -mods "{file}" | Search -nf /{SearchExpression}/ opt-3opt3 Dev:Null
- If {status} == 0
- Echo "DumpObj opt-d"{file}opt-d" -m {SearchExpression}"
- End
- End
- End opt-wopt-w "{WorkSheet}"
- Set Exit 1
-
-
- - --
- Keith Rollin
- Phantom Programmer
- Taligent, Inc.
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-